package com.tubeonfire.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TreeMap;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyOpts;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;
import com.tubeonfire.entity.Playlist;
import com.tubeonfire.model.admin.SiteConfigModel;

public class PlaylistModel {

	private static Objectify ofy;

	private static Cache cache = null;

	private static boolean isRegisted = false;

	private static ObjectifyOpts opts = null;

	private static String cacheSide = "frontEnd_";

	private static String cachePrefix = "playlistModel_";

	private static TreeMap<String, String> mapCacheKey = new TreeMap<String, String>();

	private int limit = 18;

	private int page = 1;

	private int totalResult = 0;

	private int totalPage = 1;

	private List<Playlist> listResult = new ArrayList<Playlist>();

	public int getTotalPage() {
		totalPage = totalResult / limit;
		if ((totalResult % limit) > 0) {
			totalPage += 1;
		}
		return totalPage;
	}

	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}

	public int getLimit() {
		return limit;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getTotalResult() {
		return totalResult;
	}

	public void setTotalResult(int totalResult) {
		this.totalResult = totalResult;
	}

	public List<Playlist> getListResult() {
		return listResult;
	}

	public void setListResult(List<Playlist> listResult) {
		this.listResult = listResult;
	}

	public static void init() {
		if (!isRegisted) {
			isRegisted = true;
			try {
				ObjectifyService.register(Playlist.class);
			} catch (Exception e) {
				isRegisted = false;
			}
			try {
				cache = CacheManager.getInstance().getCacheFactory()
						.createCache(Collections.emptyMap());
			} catch (CacheException e) {
				isRegisted = false;
			}
			opts = new ObjectifyOpts().setSessionCache(true);
		}
		ofy = ObjectifyService.begin(opts);
	}

	public PlaylistModel() {
		init();
	}

	@SuppressWarnings("unchecked")
	public static Playlist byId(String id, boolean fromCache) {
		init();
		Playlist obj = new Playlist();
		String prefix = cachePrefix + "id_" + id;
		if (cache != null && cache.containsKey(prefix) && fromCache) {
			obj = (Playlist) cache.get(prefix);
		} else {
			try {
				obj = ofy.get(new Key<Playlist>(Playlist.class, id));
				if (fromCache) {
					cache.put(prefix, obj);
				}
			} catch (Exception e) {
				obj = null;
			}
		}
		return obj;
	}

	@SuppressWarnings("unchecked")
	public static Playlist byAlias(String alias, boolean fromCache) {
		init();
		Playlist obj = new Playlist();
		String prefix = cachePrefix + "alias_" + alias;
		mapCacheKey.put(prefix, prefix);
		if (cache != null && cache.containsKey(prefix) && fromCache) {
			obj = (Playlist) cache.get(prefix);
		} else {
			try {
				obj = ofy.query(Playlist.class).filter("alias", alias).get();
				if (fromCache) {
					cache.put(prefix, obj);
				}
			} catch (Exception e) {
				obj = null;
			}
		}
		return obj;
	}

	@SuppressWarnings("unchecked")
	public void prepareList(boolean fromCache) {
		init();
		listResult = new ArrayList<Playlist>();
		String prefix = cacheSide + cachePrefix + "page_" + page + "_limit_"
				+ limit;
		String prefixTotalResult = cacheSide + "allPlaylistTotalResult";
		String prefixLimit = cacheSide + "allPlaylistLimit";

		mapCacheKey.put(prefix, prefix);
		if (cache != null && cache.containsKey(prefix)
				&& cache.containsKey(prefixTotalResult)
				&& cache.containsKey(prefixLimit) && fromCache) {
			listResult = (List<Playlist>) cache.get(prefix);
			totalResult = (Integer) cache.get(cacheSide
					+ "allPlaylistTotalResult");
			limit = (Integer) cache.get(cacheSide + "allPlaylistLimit");
		} else {
			int start = (page - 1) * limit;
			Query<Playlist> q = ofy.query(Playlist.class).order("-indexDate");
			totalResult = q.count();
			q = q.limit(limit).offset(start);
			for (Playlist obj : q) {
				listResult.add(obj);
			}
			if (listResult.size() > 0 && fromCache) {
				cache.put(prefix, listResult);
				cache.put(cacheSide + "allPlaylistTotalResult", totalResult);
				cache.put(cacheSide + "allPlaylistLimit", limit);
			}
		}
	}

	@SuppressWarnings("unchecked")
	public void prepareHomeList(boolean fromCache) {
		init();
		listResult = new ArrayList<Playlist>();
		limit = SiteConfigModel.get().getHomePageBlockQuantity();
		String prefix = cacheSide + cachePrefix + "homepage_limit_" + limit;
		mapCacheKey.put(prefix, prefix);
		if (cache != null && cache.containsKey(prefix) && fromCache) {
			listResult = (List<Playlist>) cache.get(prefix);
		} else {
			int start = (page - 1) * limit;
			Query<Playlist> q = ofy.query(Playlist.class).order("-indexDate");
			totalResult = q.count();
			q = q.limit(limit).offset(start);
			for (Playlist obj : q) {
				listResult.add(obj);
			}
			if (listResult.size() > 0 && fromCache) {
				cache.put(prefix, listResult);
			}
		}
	}

	public static void clearModelCache() {
		init();
		try {
			if (mapCacheKey != null && mapCacheKey.size() > 0) {
				for (String key : mapCacheKey.keySet()) {
					cache.remove(key);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
